#include "BuffEffectInfo.h"
#include "base/core/random.h"
#include "Common/TableData/SkillBuffCfg.h"
#include "BuffEffectLogicManager.h"
#include "Character/Creature.h"
#include "BuffEffectLogic.h"
#include "Character/BuffPart.h"
#include "base/core/Profiler.h"

uint32_t BuffBagEffectInfo::m_static_instance_id = 0;

BuffEffectInfo::BuffEffectInfo()
{
	m_effectType = (uint32_t)effectTypeNone;
	m_intervalTime = 0;
	m_intervalCount = 0;
	m_intervalRestCount = 0;

	m_logicHandle = nullptr;
	m_pMaster = nullptr;
	m_buffBag = nullptr;
	m_isForever = false;

	m_params.resize(MAX_BUFF_EFFECT_PRAM_NUMBER);
	for (size_t i = 0; i < m_params.size(); i++)
	{
		m_params[i] = 0;
	}
}

BuffEffectInfo::~BuffEffectInfo()
{
	g_GetTimerAxis()->KillAllTimer(this);
}

void BuffEffectInfo::copy(const BuffEffectInfo& info)
{
	if (this == &info)
	{
		return;
	}
	m_effectType = info.m_effectType;

	m_intervalTime =info.m_intervalTime;
	m_intervalCount = info.m_intervalCount;
	m_intervalRestCount = info.m_intervalRestCount;

	m_logicHandle = info.m_logicHandle;
	m_pMaster = info.m_pMaster;
	m_buffBag = info.m_buffBag;

	m_params = info.m_params;

	m_isForever = info.m_isForever;
}

BuffEffectInfo::BuffEffectInfo(const BuffEffectInfo& info)
{
	copy(info);
}

BuffEffectInfo& BuffEffectInfo::operator=(const BuffEffectInfo& info)
{
	copy(info);
	return *this;
}

bool BuffEffectInfo::InitFromData(const BuffEffectCfgInfo& buffInfo, BuffBagEffectInfo* pBuffBag, uint64_t senderCid,  int32_t param, bool isForever /* = false */)
{
	if (pBuffBag == false)
	{
		return false;
	}

	m_effectType = buffInfo.m_type;

	m_intervalTime = 0;
	m_intervalCount = 0;
	m_intervalRestCount = 0;
	m_isForever = isForever;

	m_logicHandle = nullptr;
	m_pMaster = pBuffBag->GetMaster();
	m_buffBag = pBuffBag;

	IBuffLogic* pLogic = g_GetBuffLogicManager()->GetBuffLogic(m_effectType);
	if (pLogic)
	{
		m_logicHandle = pLogic;
		if (m_logicHandle->InitFromData(buffInfo, pBuffBag, this, senderCid, m_pMaster, param) == false)
		{
			return false;
		}
	}
	else
	{
		m_logicHandle = nullptr;
	}
	return true;
}

void BuffEffectInfo::OnTimer(uint32_t nTimerId)
{
	BEGIN_PROFILE("BuffEffectInfo::OnTimer");
	OnEvent_IntervalOver();
	END_PROFILE();
}

void BuffEffectInfo::OnEvent_Active()
{
	IBuffLogic* pLogic = g_GetBuffLogicManager()->GetBuffLogic(m_effectType);
	if (pLogic)
	{
		pLogic->OnEvent_Active(this, m_pMaster);
	}
}

void BuffEffectInfo::StartInterval()
{
	if (m_intervalTime > 0)
	{
		if (m_isForever)
		{
			if (!g_GetTimerAxis()->SetTimer(0, m_intervalTime, dynamic_cast<ITimerHandler*>(this)))
			{
				LogErrFmtPrint("g_GetTimerAxis()->SetTimer(0, m_intervalTime, this, count) failed");
				return;
			}
		}
		else if (GetContinuanceTime() > 0)
		{
			m_intervalCount = GetContinuanceTime() / m_intervalTime;
			if (m_intervalCount == 0)
			{
				m_intervalCount++;
			}

			if (!g_GetTimerAxis()->SetTimer(0, m_intervalTime, dynamic_cast<ITimerHandler*>(this), m_intervalCount))
			{
				LogErrFmtPrint("g_GetTimerAxis()->SetTimer(0, m_intervalTime, this, count) failed");
				return;
			}
		}
	}
}

void BuffEffectInfo::StopInternal()
{
	g_GetTimerAxis()->KillTimer(0, dynamic_cast<ITimerHandler*>(this));
}

void BuffEffectInfo::OnEvent_FadeOut()
{
	IBuffLogic* pLogic = g_GetBuffLogicManager()->GetBuffLogic(m_effectType);
	if (pLogic)
	{
		pLogic->OnEvent_FadeOut(this, m_pMaster);
		StopInternal();
	}
}

void BuffEffectInfo::OnEvent_IntervalOver()
{
	IBuffLogic* pLogic = g_GetBuffLogicManager()->GetBuffLogic(m_effectType);
	if (pLogic)
	{
		pLogic->OnEvent_Active(this, m_pMaster);
	}

	if (!m_isForever)
	{
		m_intervalRestCount++;
		if (m_intervalRestCount >= m_intervalCount)
		{
			m_buffBag->BuffEffect_OnEffectFadeOut(false);
		}
	}
}

bool BuffEffectInfo::IsExistParamIndex(uint32_t index)
{
	if (index >= m_params.size())
	{
		return false;
	}
	return true;
}

int32_t	BuffEffectInfo::GetParamByIndex(uint32_t index)
{
	if (index >= m_params.size())
	{
		return 0;
	}

	return m_params[index];
}

void BuffEffectInfo::SetParamByIndex(uint32_t index, int32_t value)
{
	if (index >= m_params.size())
	{
		m_params.resize(index+1);
	}
	m_params[index] = value;
}

void BuffEffectInfo::SetParamSize(uint32_t size)
{
	if (m_params.size() < (size))
	{
		m_params.resize(size);
	}
}

void BuffEffectInfo::SetParam(const std::vector<int32_t>& vec)
{
	m_params = vec;
}

std::vector<int32_t>& BuffEffectInfo::GetParam()
{
	return m_params;
}

const std::vector<int32_t>& BuffEffectInfo::GetParam() const
{
	return m_params;
}


uint32_t BuffEffectInfo::GetEffectType() const 
{ 
	return m_effectType; 
}

void BuffEffectInfo::SetEffectType(uint32_t type) 
{ 
	m_effectType = type; 
}

uint32_t BuffEffectInfo::GetContinuanceTime() const 
{ 
	return m_buffBag->GetStateBagTime(); 
}

uint32_t BuffEffectInfo::GetIntervalTime() const 
{ 
	return m_intervalTime; 
}

void BuffEffectInfo::SetIntervalTime(uint32_t value) 
{ 
	m_intervalTime = value; 
}

IBuffLogic* BuffEffectInfo::GetBuffLogic() const 
{ 
	return m_logicHandle; 
}

void BuffEffectInfo::SetBuffLogic(IBuffLogic* pLogic) 
{ 
	m_logicHandle = pLogic; 
}

uint64_t BuffEffectInfo::GetSenderId() const
{ 
	return m_buffBag->GetSenderId(); 
}

Creature* BuffEffectInfo::GetMaster() const 
{ 
	return m_pMaster; 
}

void BuffEffectInfo::SetMaster(Creature* pMaster) 
{ 
	m_pMaster = pMaster; 
}

uint32_t BuffEffectInfo::GetSkillId() const 
{ 
	return m_buffBag->GetSkillId(); 
}

uint32_t BuffEffectInfo::GetSkillLevel() const 
{ 
	return m_buffBag->GetSkillLevel(); 
}

BuffBagEffectInfo* BuffEffectInfo::GetBuffBag() const 
{ 
	return m_buffBag; 
}

BuffBagEffectInfo::BuffBagEffectInfo()
{
	m_instId = ++m_static_instance_id;
	m_stateBagId = 0;
	m_stateBagConfigData = nullptr;
	m_stateBagTime = 0;
	m_delayedTime = 0;
	m_isActivated = false;

	m_skillId = 0;
	m_skillLevel = 0;
	m_startTime = 0;
	m_senderId = 0;
	m_pMaster = nullptr;
	m_isForever = false;
	m_status = BuffBagStatus::BUFF_BAG_STATUS_CREATED;
	m_buffPart = nullptr;
	m_lastCdTime = 0;
	m_targetType = BUFF_BAG_TARGET_TYPE_ENEMY;
}

BuffBagEffectInfo::~BuffBagEffectInfo()
{
	UnRegisterMessage();
	g_GetTimerAxis()->KillAllTimer(this);
	Clear();
}

bool BuffBagEffectInfo::LoadFromDB(const ::ProtoBuf::BuffBagInfo& buffInfo)
{
	const BuffBagEffectCfgInfo* pBuffCfgInfo = g_GetBuffBagEffectCfgMgr()->FindBuffBag(buffInfo.statebagid());
	if (pBuffCfgInfo == nullptr)
	{
		return false;
	}

	m_stateBagId = buffInfo.statebagid();
	m_stateBagTime = buffInfo.statebagtime();
	m_startTime = buffInfo.starttime();
	m_senderId = buffInfo.sendercid();

	m_stateBagConfigData = pBuffCfgInfo;
	m_skillId = buffInfo.skillid();
	m_skillLevel = buffInfo.skilllevel();
	m_isActivated = true;
	m_isForever = buffInfo.isforever();
	m_targetType = (BuffTargetType)buffInfo.targettype();

	m_status = (BuffBagStatus)buffInfo.status();

	if (m_status == BuffBagStatus::BUFF_BAG_STATUS_DELAYED_START)
	{
		m_delayedTime = buffInfo.delayedtime();
		if (g_GetGlobalServerTime()->Tick() - m_startTime > m_delayedTime)
		{
			if (m_isForever == false)
			{
				if (g_GetGlobalServerTime()->Tick() - m_startTime > m_delayedTime + m_stateBagTime)
				{
					return false;
				}
				else
				{
					m_status = BUFF_BAG_STATUS_REFIX_START;
					m_delayedTime = 0;
					m_stateBagTime = m_stateBagTime - (g_GetGlobalServerTime()->Tick() - m_startTime - m_delayedTime);
					m_startTime = g_GetGlobalServerTime()->Tick();
				}
			}
		}
	}
	else
	{
		if (m_isForever == false)
		{
			if (g_GetGlobalServerTime()->Tick() - m_startTime > m_stateBagTime)
			{
				return false;
			}
			else
			{
				m_stateBagTime = m_stateBagTime - (g_GetGlobalServerTime()->Tick() - m_startTime);
				m_startTime = g_GetGlobalServerTime()->Tick();
			}
		}
	}

	std::vector<int32_t> tmpParams;
	for(int j = 0; j < buffInfo.params_size(); j++)
	{
		tmpParams.push_back(buffInfo.params(j));
	}

	if (tmpParams.size() < pBuffCfgInfo->m_buffList.size())
	{
		LogDebugFmtPrint("the buff bag params != buff list size skillId:%d, param count:%d, bufflist count:%d", m_skillId, tmpParams.size(), pBuffCfgInfo->m_buffList.size());

		while (tmpParams.size() < pBuffCfgInfo->m_buffList.size())
		{
			tmpParams.push_back(0);
		}
	}

	m_params = std::move(tmpParams);
	for (size_t i = 0; i < pBuffCfgInfo->m_buffList.size() && i < m_params.size(); i++)
	{
		const BuffEffectCfgInfo& buffInfo = pBuffCfgInfo->m_buffList[i];
		if (buffInfo.m_type == effectTypeNone)
		{
			continue;
		}

		BuffEffectInfo *buff = CreateBuffEffectInfo();

		if (buff->InitFromData(buffInfo, this, m_senderId, m_params[i]) == false)
		{
			LogDebugFmtPrint("siillId:%d buffStateBagId%d buffType:%d param:%d InitFromData failed! ", m_skillId, m_stateBagId, buffInfo.m_type, m_params[i]);
			DeleteBuffEffectInfo(buff);
			return false;
		}

		if (buffInfo.m_type == effectTypeRefixSkill)
		{
			RegisterMessage(EVENT_ATTACK_SOMEBODY);
		}

		m_buffList.push_back(buff);
	}

	if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_SKILL_TRIGGER_START
				|| pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_PROP_AND_SKILL_TRIGGER_START
				|| pBuffCfgInfo->m_pCfgInfo->startType == BUFF_BAG_STATUS_USE_SKILL)
		{
			RegisterMessage(EVENT_USE_SKILL_ATTACK);
		}
		else if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_KILLING_START)
		{
			RegisterMessage(EVENT_CREATURE_DEAD);
		}
		else if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_BE_ATTACTED_START)
		{
			RegisterMessage(EVENT_UNDER_ATTACK);
		}
		else if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_ATTACK_START
				|| pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_ROLE_PU_ATTACK_START
				|| pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_PET_PU_ATTACK_START)
		{
			RegisterMessage(EVENT_ATTACK_SOMEBODY);
		}
		else if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_WILLING_DIED_START)
		{
			RegisterMessage(EVENT_CREATURE_WILLING_DIED);
		}


	return true;
}

bool BuffBagEffectInfo::InitFromData(uint64_t senderCid, uint32_t skillId, uint32_t skillLevel, uint32_t stateBagId,
		uint32_t stateBagTime, const std::vector<int32_t>& params, bool isForever, uint32_t targetType)
{
	const BuffBagEffectCfgInfo* pBuffCfgInfo = g_GetBuffBagEffectCfgMgr()->FindBuffBag(stateBagId);
	if (pBuffCfgInfo == nullptr)
	{
		return false;
	}

	m_stateBagId = stateBagId;
	m_stateBagTime = stateBagTime;
	m_startTime = g_GetGlobalServerTime()->Tick();
	m_senderId = senderCid;

	m_stateBagConfigData = pBuffCfgInfo;
	m_skillId = skillId;
	m_skillLevel = skillLevel;
	m_isActivated = true;
	m_isForever = isForever;
	m_targetType = (BuffTargetType)targetType;

	m_status = (BuffBagStatus)pBuffCfgInfo->m_pCfgInfo->startType;
	if (m_status == BuffBagStatus::BUFF_BAG_STATUS_DELAYED_START)
	{
		m_delayedTime = pBuffCfgInfo->m_pCfgInfo->delayTime;
	}

	std::vector<int32_t> tmpParams = params;

	if (params.size() < pBuffCfgInfo->m_buffList.size())
	{
		LogDebugFmtPrint("the buff bag params != buff list size skillId:%d, param count:%d, bufflist count:%d", skillId, params.size(), pBuffCfgInfo->m_buffList.size());

		while (tmpParams.size() < pBuffCfgInfo->m_buffList.size())
		{
			tmpParams.push_back(0);
		}
	}

	m_params = std::move(tmpParams);

	for (size_t i = 0; i < pBuffCfgInfo->m_buffList.size() && i < m_params.size(); i++)
	{
		const BuffEffectCfgInfo& buffInfo = pBuffCfgInfo->m_buffList[i];
		if (buffInfo.m_type == effectTypeNone)
		{
			continue;
		}

		BuffEffectInfo *buff = CreateBuffEffectInfo();
		if (buff == nullptr)
		{
			return false;
		}

		if (buff->InitFromData(buffInfo, this, m_senderId, m_params[i], m_isForever) == false)
		{
			LogDebugFmtPrint("siillId:%d buffStateBagId%d buffType:%d param:%d InitFromData failed! ", skillId, stateBagId, buffInfo.m_type, m_params[i]);
			DeleteBuffEffectInfo(buff);
			return false;
		}

		if (buffInfo.m_type == effectTypeRefixSkill)
		{
			RegisterMessage(EVENT_ATTACK_SOMEBODY);
		}

		m_buffList.push_back(buff);
	}

	if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_SKILL_TRIGGER_START
			|| pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_PROP_AND_SKILL_TRIGGER_START
			|| pBuffCfgInfo->m_pCfgInfo->startType == BUFF_BAG_STATUS_USE_SKILL)
	{
		RegisterMessage(EVENT_USE_SKILL_ATTACK);
	}
	else if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_KILLING_START)
	{
		RegisterMessage(EVENT_CREATURE_DEAD);
	}
	else if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_BE_ATTACTED_START)
	{
		RegisterMessage(EVENT_UNDER_ATTACK);
	}
	else if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_ATTACK_START
			|| pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_ROLE_PU_ATTACK_START
			|| pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_PET_PU_ATTACK_START)
	{
		RegisterMessage(EVENT_ATTACK_SOMEBODY);
	}
	else if (pBuffCfgInfo->m_pCfgInfo->startType == BuffBagStatus::BUFF_BAG_STATUS_WILLING_DIED_START)
	{
		RegisterMessage(EVENT_CREATURE_WILLING_DIED);
	}

	return true;
}

uint64_t BuffBagEffectInfo::CountRestTime() const
{
	uint64_t useTime = g_GetGlobalServerTime()->Tick() - m_startTime;
	return m_stateBagTime < useTime ? 0 : m_stateBagTime - useTime;
}

bool BuffBagEffectInfo::IsContainEndType(int32_t endType) const
{
	if (m_stateBagConfigData)
	{
		return m_stateBagConfigData->IsContainEndType(endType);
	}
	return true;
}


void			BuffBagEffectInfo::ToClientMsg(ProtoBuf::BuffBagDetailInfo& detailInfo) const
{
	//detailInfo.set_sender_cid(GetSenderId());
	//detailInfo.set_recver_cid(m_pMaster->GetCid());

	detailInfo.set_buff_bag_inst_id(GetInstId());
	detailInfo.set_buff_bag_id(GetStateBagId());
	if (m_isForever)
	{
		uint64_t ntime = 7776000000;//3*30*24*60*60*1000
		detailInfo.set_continuance_time(ntime);
	}
	else
	{
		if (m_stateBagTime == 0)
		{
			detailInfo.set_continuance_time(3000);
		}
		else
		{
			detailInfo.set_continuance_time(CountRestTime());
		}
	}
	detailInfo.set_delayed_time(GetDelayedTime());
}


void BuffBagEffectInfo::ToMsg(ProtoBuf::BuffBagDetailInfo& detailInfo) const
{
	detailInfo.set_sender_cid(GetSenderId());
	detailInfo.set_recver_cid(m_pMaster->GetCid());
	
	detailInfo.set_buff_bag_inst_id(GetInstId());
	detailInfo.set_buff_bag_id(GetStateBagId());
	if (m_isForever)
	{
		uint64_t ntime = 7776000000;//3*30*24*60*60*1000
		detailInfo.set_continuance_time(ntime);
	}
	else
	{
		if (m_stateBagTime == 0)
		{
			detailInfo.set_continuance_time(3000);
		}
		else
		{
			detailInfo.set_continuance_time(CountRestTime());
		}
	}
	detailInfo.set_delayed_time(GetDelayedTime());
}

void BuffBagEffectInfo::FromMsg(const ProtoBuf::BuffBagDetailInfo& detailInfo)
{

}

void BuffBagEffectInfo::BuffEffect_StartTimer()
{
	bool isStartTimer = true;
	if (GetStatus() == BuffBagStatus::BUFF_BAG_STATUS_DELAYED_START)
	{
		StartDelayedTimer();
		return;
	}

	for (auto newIt = m_buffList.begin(); newIt != m_buffList.end(); newIt++)
	{
		BuffEffectInfo* buff = *newIt;

		if (buff->GetIntervalTime() > 0)
		{
			buff->StartInterval();
			isStartTimer = false;
		}
	}

	if (!m_isForever)
	{
		if (isStartTimer)
		{
			if (GetStateBagTime() >=0)
			{
				StartTimer();
			}
		}
	}
	else
	{
		if (isStartTimer)
		{
			StartTimer();
		}
	}
	return;
}

//
void BuffBagEffectInfo::BuffEffect_OnEffectActived()
{
	for (auto newIt = m_buffList.begin(); newIt != m_buffList.end(); newIt++)
	{
		BuffEffectInfo* buff = *newIt;

		if (buff->GetIntervalTime() <= 0)
		{
			buff->OnEvent_Active();
		}
	}

	return;
}

void BuffBagEffectInfo::BuffEffect_SendStartEffectMsg()
{
	BuffBagDetailInfo detailInfo;
	ToMsg(detailInfo);
	m_pMaster->BroadCastData(LOGIC_TO_CLIENT_START_BUFF_BAG, &detailInfo, true);
}

void BuffBagEffectInfo::BuffEffect_OnEffectFadeOut(bool isSendEndEffect /*= true*/)
{
	EndTimer();
	if (m_pMaster)
	{
		BuffPart* pBuffPart = static_cast<BuffPart*>(m_pMaster->GetPart(PART_BUFF));
		if (pBuffPart)
		{
			//SetActivated(false); 一定要放在前面，否则会导致死循环
			SetActivated(false);
			pBuffPart->BuffEffect_CleanupAllFadeOutEffects(this, isSendEndEffect);
		}
	}
}

void BuffBagEffectInfo::OnTimer(uint32_t nTimerId)
{
	switch(nTimerId)
	{
	case ENUM_BUFF_BAG_TIMER:
	{
		BuffEffect_OnEffectFadeOut(false);
	}
	break;
	case ENUM_BUFF_BAG_TIMER_DELAYED:
	{
		HandleDelayedTimer();
	}
	break;
	default:
		break;
	}
}

void BuffBagEffectInfo::HandleDelayedTimer()
{
	SetDelayedTime(0);
	SetStartTime(g_GetGlobalServerTime()->Tick());
	SetStatus(BuffBagStatus::BUFF_BAG_STATUS_REFIX_START);

	BuffEffect_OnEffectActived();
	BuffEffect_StartTimer();
	m_buffPart->BuffEffect_EffectClassifed(this);
}

void BuffBagEffectInfo::EndDelayedTimer()
{
	g_GetTimerAxis()->KillTimer(ENUM_BUFF_BAG_TIMER_DELAYED, dynamic_cast<ITimerHandler*>(this));
}

void BuffBagEffectInfo::StartDelayedTimer()
{
	g_GetTimerAxis()->KillTimer(ENUM_BUFF_BAG_TIMER_DELAYED, dynamic_cast<ITimerHandler*>(this));
	if (!g_GetTimerAxis()->SetTimer(ENUM_BUFF_BAG_TIMER_DELAYED, GetDelayedTime(), dynamic_cast<ITimerHandler*>(this), 1))
	{
		LogErrFmtPrint("g_GetTimerAxis()->SetTimer(0, m_stateBagTime, this, 1) failed");
		return;
	}
}

void BuffBagEffectInfo::StartTimer()
{
	g_GetTimerAxis()->KillTimer(ENUM_BUFF_BAG_TIMER, dynamic_cast<ITimerHandler*>(this));
	if (!m_isForever)
	{
		if (m_stateBagTime > 0)
		{
			if (!g_GetTimerAxis()->SetTimer(ENUM_BUFF_BAG_TIMER, m_stateBagTime, dynamic_cast<ITimerHandler*>(this), 1))
			{
				LogErrFmtPrint("g_GetTimerAxis()->SetTimer(0, m_stateBagTime, this, 1) failed");
				return;
			}
		}
		else
		{
			if (!g_GetTimerAxis()->SetTimer(ENUM_BUFF_BAG_TIMER, 1, dynamic_cast<ITimerHandler*>(this), 1))
			{
				LogErrFmtPrint("g_GetTimerAxis()->SetTimer(0, m_stateBagTime, this, 1) failed");
				return;
			}
		}
	}
}

void BuffBagEffectInfo::EndTimer()
{
	g_GetTimerAxis()->KillTimer(0, dynamic_cast<ITimerHandler*>(this));
}

void BuffBagEffectInfo::Clear()
{
	for (std::list<BuffEffectInfo*>::iterator it = m_buffList.begin(); it != m_buffList.end(); it++)
	{
		BuffEffectInfo* pBuff = *it;
		DeleteBuffEffectInfo(pBuff);
		*it = nullptr;
	}

	m_buffList.clear();
}

void BuffBagEffectInfo::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	if (m_pMaster->IsDead() || this->IsActivated() == false)
	{
		return;
	}

	switch(nEventID)
	{
	case EVENT_USE_SKILL_ATTACK:
	{
		skillAttackEvent* attackInfo = (skillAttackEvent*)pContext;
		if (attackInfo)
		{
			if (IsActivated())
			{
				if (GetStatus() == BuffBagStatus::BUFF_BAG_STATUS_SKILL_TRIGGER_START && attackInfo->skillId != 0)
				{
					if (GetEffectCfgInfo()->IsContainStartValue((int32_t)attackInfo->skillId))
					{
						uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
						if (stateBagCd > 0)
						{
							if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
							{
								return;
							}

							m_lastCdTime = g_GetGlobalServerTime()->Tick();
						}

						m_buffPart->GetBuffEventParam().m_targetCid = attackInfo->victim;
						m_buffPart->GetBuffEventParam().m_damagedValue = attackInfo->sufferedValue;
						BuffEffect_OnEffectActived();
						m_buffPart->ClearBuffEventParam();
					}
				}
				else if (GetStatus() == BuffBagStatus::BUFF_BAG_STATUS_PROP_AND_SKILL_TRIGGER_START)
				{
					const SkillSkillCfgInfo *pInfo = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(attackInfo->skillId);
					if (pInfo == nullptr)
					{
						return;
					}

					if (GetEffectCfgInfo()->m_startTypeValueProf == 0 || GetEffectCfgInfo()->m_startTypeValueProf == m_pMaster->GetAttr(C_PROF))
					{
						if (GetEffectCfgInfo()->m_startTypeValueSkillType == 0 || GetEffectCfgInfo()->m_startTypeValueSkillType == (uint32_t)pInfo->skillType)
						{
							uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
							if (stateBagCd > 0)
							{
								if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
								{
									return;
								}

								m_lastCdTime = g_GetGlobalServerTime()->Tick();
							}
							m_buffPart->GetBuffEventParam().m_targetCid = attackInfo->victim;
							m_buffPart->GetBuffEventParam().m_damagedValue = attackInfo->sufferedValue;
							BuffEffect_OnEffectActived();
							m_buffPart->ClearBuffEventParam();
						}
					}
				}
				else if (GetStatus() == BuffBagStatus::BUFF_BAG_STATUS_USE_SKILL)
				{
					uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
					if (stateBagCd > 0)
					{
						if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
						{
							return;
						}

						m_lastCdTime = g_GetGlobalServerTime()->Tick();
					}
					m_buffPart->GetBuffEventParam().m_targetCid = attackInfo->victim;
					m_buffPart->GetBuffEventParam().m_damagedValue = attackInfo->sufferedValue;
					BuffEffect_OnEffectActived();
					m_buffPart->ClearBuffEventParam();
				}
			}
		}
	}
	break;
	case EVENT_CREATURE_DEAD:
	{
		DieEvent* devEvent = (DieEvent*)pContext;
		if (devEvent)
		{
			if (m_pMaster->GetCid() == devEvent->killerCid)
			{
				uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
				if (stateBagCd > 0)
				{
					if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
					{
						return;
					}

					m_lastCdTime = g_GetGlobalServerTime()->Tick();
				}
				BuffEffect_OnEffectActived();
			}
		}
	}
	break;
	case EVENT_CREATURE_WILLING_DIED:
	{
		uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
		if (stateBagCd > 0)
		{
			if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
			{
				return;
			}

			m_lastCdTime = g_GetGlobalServerTime()->Tick();
		}
		BuffEffect_OnEffectActived();
	}
	break;
	case EVENT_ATTACK_SOMEBODY:
	{
		skillAttackEvent* attackInfo = (skillAttackEvent*)pContext;
		if (m_pMaster->HasBuffStateRefixSkill())
		{
			if (attackInfo->skillId == this->m_skillId || attackInfo->victim == 0)
			{
				return;
			}
			for (auto newIt = m_buffList.begin(); newIt != m_buffList.end(); newIt++)
			{
				BuffEffectInfo* buff = *newIt;

				if (buff->GetEffectType() == effectTypeRefixSkill)
				{
					m_buffPart->GetBuffEventParam().m_skillId = attackInfo->skillId;
					BuffEffect_OnEffectActived();
					m_buffPart->ClearBuffEventParam();
				}
			}
		}

		if (GetStatus() == BuffBagStatus::BUFF_BAG_STATUS_ATTACK_START)
		{
			Scene* pCurScene = m_pMaster->GetScene();
			if (pCurScene)
			{
				Creature* pTarget = pCurScene->GetCreature(attackInfo->victim);
				if (pTarget)
				{
					if (!m_pMaster->IsFriendSide(pTarget))
					{
						uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
						if (stateBagCd > 0)
						{
							if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
							{
								return;
							}

							m_lastCdTime = g_GetGlobalServerTime()->Tick();
						}
						m_buffPart->GetBuffEventParam().m_targetCid = attackInfo->victim;
						m_buffPart->GetBuffEventParam().m_damagedValue = attackInfo->sufferedValue;
						BuffEffect_OnEffectActived();
						m_buffPart->ClearBuffEventParam();
					}
				}
			}
		}
		else if (GetStatus() == BuffBagStatus::BUFF_BAG_STATUS_ROLE_PU_ATTACK_START)
		{
			auto pSkillInfo = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(attackInfo->skillId);
			if (pSkillInfo && pSkillInfo->skillType == process_Nomal)
			{

				if (m_pMaster->CreatureKind() == CREATURE_PLAYER)
				{
					uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
					if (stateBagCd > 0)
					{
						if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
						{
							return;
						}

						m_lastCdTime = g_GetGlobalServerTime()->Tick();
					}
					m_buffPart->GetBuffEventParam().m_targetCid = attackInfo->victim;
					m_buffPart->GetBuffEventParam().m_damagedValue = attackInfo->sufferedValue;
					BuffEffect_OnEffectActived();
					m_buffPart->ClearBuffEventParam();
				}
			}
		}
		else if (GetStatus() == BuffBagStatus::BUFF_BAG_STATUS_PET_PU_ATTACK_START)
		{
			auto pSkillInfo = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(attackInfo->skillId);
			if (pSkillInfo && pSkillInfo->skillType == process_Nomal && attackInfo->victim != 0)
			{
				if (m_pMaster->CreatureKind() == CREATURE_PET)
				{
					uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
					if (stateBagCd > 0)
					{
						if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
						{
							return;
						}

						m_lastCdTime = g_GetGlobalServerTime()->Tick();
					}
					m_buffPart->GetBuffEventParam().m_targetCid = attackInfo->victim;
					m_buffPart->GetBuffEventParam().m_damagedValue = attackInfo->sufferedValue;
					BuffEffect_OnEffectActived();
					m_buffPart->ClearBuffEventParam();
				}
			}
		}
	}
	break;
	case EVENT_UNDER_ATTACK:
	{
		skillAttackEvent* attackInfo = (skillAttackEvent*)pContext;
		if (GetStatus() == BuffBagStatus::BUFF_BAG_STATUS_BE_ATTACTED_START)
		{
			Scene* pCurScene = m_pMaster->GetScene();
			if (pCurScene)
			{
				Creature* pTarget = pCurScene->GetCreature(attackInfo->attacker);
				if (pTarget)
				{
					if (!m_pMaster->IsFriendSide(pTarget))
					{
						uint64_t stateBagCd = (uint64_t)CommonApi::StrToInt(this->GetEffectCfgInfo()->m_pCfgInfo->stateBagCd);
						if (stateBagCd > 0)
						{
							if (m_lastCdTime + stateBagCd > g_GetGlobalServerTime()->Tick())
							{
								return;
							}

							m_lastCdTime = g_GetGlobalServerTime()->Tick();
						}
						m_buffPart->GetBuffEventParam().m_targetCid = attackInfo->attacker;
						m_buffPart->GetBuffEventParam().m_damagedValue = attackInfo->sufferedValue;
						BuffEffect_OnEffectActived();
						m_buffPart->ClearBuffEventParam();
					}
				}
			}
		}
	}
	break;
	default:

		break;
	}
}


//������Ϣ
void BuffBagEffectInfo::RegisterMessage(EventId id)
{
	if (id == EVENT_CREATURE_DEAD)
	{
		g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), id, m_pMaster->GetCid(), CREATURE_MONSTER, NULL);
		g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), id, 0, CREATURE_PLAYER, NULL);
		g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), id, m_pMaster->GetCid(), CREATURE_NPC, NULL);
	}
	else
	{
		g_GetEvent()->Subscribe(dynamic_cast<IEventExecuteSink*>(this), id, m_pMaster->GetCid(), 0, NULL);
	}
}

//ȡ��������Ϣ
void BuffBagEffectInfo::UnRegisterMessage()
{
	g_GetEvent()->UnSubscribeAll(dynamic_cast<IEventExecuteSink*>(this));
}
